package cn.sciento.transfer.infra.datasource;

import cn.sciento.core.exception.CommonException;import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import cn.sciento.transfer.infra.datasource.factory.DataSourceContextHolder;
import cn.sciento.transfer.infra.datasource.provider.AbstractDataSourceProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.CollectionUtils;

public class DynamicRoutingDataSource extends AbstractRoutingDataSource implements InitializingBean {
  private static Logger LOGGER = LoggerFactory.getLogger(DynamicRoutingDataSource.class);
  
  private static Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<>();
  
  private List<AbstractDataSourceProvider> dataSourceProviderList;
  
  public DynamicRoutingDataSource(List<AbstractDataSourceProvider> dataSourceProviderList) {
    this.dataSourceProviderList = dataSourceProviderList;
    if (!CollectionUtils.isEmpty(dataSourceProviderList)) {
      dataSourceProviderList.forEach((item) -> {
        if (!CollectionUtils.isEmpty(item.loadDataSources())) {
          item.loadDataSources().forEach((key, value) -> {
            dataSourceMap.putIfAbsent(key, value);
          });
        }

      });
    }

    if (!dataSourceMap.containsKey("Default")) {
      throw new CommonException("must provider default data source.");
    }
  }
  
  protected DataSource determineDataSource() {
    DataSource dataSource = dataSourceMap.getOrDefault(DataSourceContextHolder.getDataSourceLookupKey(), dataSourceMap.get("Default"));
    LOGGER.debug("======================Lookup Key: [{}]======================", DataSourceContextHolder.getDataSourceLookupKey());
    if (dataSource instanceof com.zaxxer.hikari.HikariDataSource) {
      LOGGER.debug("======================HikariDataSource======================");
    } else if (dataSource instanceof com.alibaba.druid.pool.DruidDataSource) {
      LOGGER.debug("======================DruidDataSource======================");
    } else if (dataSource instanceof org.apache.commons.dbcp2.BasicDataSource) {
      LOGGER.debug("======================BasicDataSource======================");
    } else if (dataSource instanceof com.mchange.v2.c3p0.ComboPooledDataSource) {
      LOGGER.debug("======================ComboPooledDataSource======================");
    } else {
      LOGGER.debug("======================No Choosen======================");
    } 
    return dataSource;
  }
  
  public void afterPropertiesSet() throws Exception {}
  
  public static void runtimeLoadDataSource(String key, DataSource dataSource) {
    dataSourceMap.putIfAbsent(key, dataSource);
  }
}
